using System;
using System.Collections.Generic;
using System.Linq;

namespace MT5Trade.Models
{
    /// <summary>
    /// 交易时机优化器 - 基于GARCH波动率预测的交易时机优化系统
    /// 整合GARCH模型预测、波动率聚类分析和交易时机评分，
    /// 为交易决策提供科学的时机选择建议
    /// </summary>
    public class TradingTimingOptimizer
    {
        #region 常量定义

        // 波动率环境阈值
        public const double LOW_VOLATILITY_THRESHOLD = 0.01;       // 低波动阈值1%
        public const double MEDIUM_VOLATILITY_THRESHOLD = 0.02;    // 中等波动阈值2%
        public const double HIGH_VOLATILITY_THRESHOLD = 0.04;      // 高波动阈值4%
        
        // 评分权重
        public const double VOLATILITY_SCORE_WEIGHT = 0.4;         // 波动率评分权重
        public const double TREND_SCORE_WEIGHT = 0.3;              // 趋势评分权重
        public const double PREDICTION_SCORE_WEIGHT = 0.3;         // 预测评分权重
        
        // 时机评分等级
        public const double EXCELLENT_TIMING_THRESHOLD = 0.8;      // 优秀时机阈值80%
        public const double GOOD_TIMING_THRESHOLD = 0.6;           // 良好时机阈值60%
        public const double POOR_TIMING_THRESHOLD = 0.4;           // 较差时机阈值40%
        
        // 预测时间范围
        public const int PREDICTION_DAYS = 5;                      // 预测天数
        public const int HISTORICAL_WINDOW = 252;                  // 历史数据窗口（1年）
        
        // 更新频率控制
        public const int UPDATE_INTERVAL_MINUTES = 15;             // 更新间隔15分钟
        
        #endregion

        #region 私有字段

        private readonly GarchModel _garchModel;
        private readonly VolatilityClusterAnalyzer _volatilityAnalyzer;
        private readonly TradingTimingScorer _timingScorer;
        private readonly List<double> _historicalReturns;
        private readonly List<double> _volatilityPredictions;
        private DateTime _lastUpdateTime;
        
        // 当前市场状态
        private ATRCalculator.VolatilityEnvironment _currentVolatilityEnvironment;
        private double _currentVolatilityPrediction;
        private double _currentTrendStrength;
        private TradingTimingScore _lastTimingScore;
        
        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化交易时机优化器
        /// </summary>
        public TradingTimingOptimizer()
        {
            _garchModel = new GarchModel();
            _volatilityAnalyzer = new VolatilityClusterAnalyzer();
            _timingScorer = new TradingTimingScorer();
            _historicalReturns = new List<double>();
            _volatilityPredictions = new List<double>();
            _lastUpdateTime = DateTime.MinValue;
            _currentVolatilityEnvironment = ATRCalculator.VolatilityEnvironment.Medium;
            _lastTimingScore = new TradingTimingScore();
        }

        /// <summary>
        /// 使用历史数据初始化优化器
        /// </summary>
        /// <param name="historicalReturns">历史收益率数据</param>
        public TradingTimingOptimizer(List<double> historicalReturns) : this()
        {
            if (historicalReturns?.Count >= HISTORICAL_WINDOW)
            {
                _historicalReturns.AddRange(historicalReturns.TakeLast(HISTORICAL_WINDOW));
                InitializeModels();
            }
        }

        #endregion

        #region 核心优化方法

        /// <summary>
        /// 获取当前交易时机评分
        /// 综合考虑波动率环境、趋势强度和GARCH预测结果
        /// </summary>
        /// <param name="currentPrice">当前价格</param>
        /// <param name="isLongPosition">是否多头仓位</param>
        /// <returns>交易时机评分结果</returns>
        public TradingTimingScore GetTradingTimingScore(double currentPrice, bool isLongPosition)
        {
            try
            {
                // 检查是否需要更新模型
                if (ShouldUpdateModels())
                {
                    UpdateModels();
                }

                // 1. 计算波动率环境评分
                var volatilityScore = CalculateVolatilityEnvironmentScore();

                // 2. 计算趋势强度评分
                var trendScore = CalculateTrendStrengthScore(isLongPosition);

                // 3. 计算GARCH预测评分
                var predictionScore = CalculateGarchPredictionScore();

                // 4. 使用新的交易时机评分系统进行增强评分
                double enhancedVolatilityScore = volatilityScore;
                double enhancedTrendScore = trendScore;
                double marketLiquidity = EstimateMarketLiquidity(); // 估算市场流动性

                if (_historicalReturns.Count > 0)
                {
                    // 使用TradingTimingScorer进行详细评分
                    var detailedScore = _timingScorer.CalculateTimingScore(
                        _currentVolatilityPrediction,
                        _currentTrendStrength,
                        marketLiquidity,
                        currentPrice,
                        null
                    );

                    // 更新评分系统的性能统计
                    // 这里可以根据实际交易结果来更新，暂时使用评分作为成功指标
                    bool tradingSuccess = detailedScore.OverallScore >= 60.0;
                    _timingScorer.UpdatePerformanceStats(
                        ConvertVolatilityEnvironment(_currentVolatilityEnvironment),
                        tradingSuccess,
                        detailedScore.OverallScore - 50.0 // 简化的盈亏估算
                    );

                    // 使用增强的评分结果
                    enhancedVolatilityScore = Math.Max(volatilityScore, detailedScore.VolatilityScore / 100.0);
                    enhancedTrendScore = Math.Max(trendScore, detailedScore.TrendScore / 100.0);
                }

                // 4. 综合评分计算 - 使用增强后的评分
                var overallScore = (enhancedVolatilityScore * VOLATILITY_SCORE_WEIGHT) +
                                 (enhancedTrendScore * TREND_SCORE_WEIGHT) +
                                 (predictionScore * PREDICTION_SCORE_WEIGHT);

                // 5. 生成交易时机建议
                var timingAdvice = GenerateTradingAdvice(overallScore, isLongPosition);

                var result = new TradingTimingScore
                {
                    OverallScore = overallScore,
                    VolatilityScore = enhancedVolatilityScore,
                    TrendScore = enhancedTrendScore,
                    PredictionScore = predictionScore,
                    VolatilityEnvironment = _currentVolatilityEnvironment,
                    PredictedVolatility = _currentVolatilityPrediction,
                    TrendStrength = _currentTrendStrength,
                    TimingAdvice = timingAdvice,
                    CalculationTime = DateTime.Now,
                    IsReliable = _historicalReturns.Count >= HISTORICAL_WINDOW
                };

                _lastTimingScore = result;
                return result;
            }
            catch (Exception ex)
            {
                // 返回保守的评分结果
                return new TradingTimingScore
                {
                    OverallScore = 0.5,
                    TimingAdvice = TimingAdvice.Caution,
                    IsReliable = false,
                    ErrorMessage = $"交易时机评分计算失败: {ex.Message}"
                };
            }
        }

        /// <summary>
        /// 更新历史数据并重新计算预测
        /// </summary>
        /// <param name="newReturn">新的收益率数据</param>
        /// <param name="newPrice">新的价格数据</param>
        public void UpdateData(double newReturn, double newPrice)
        {
            try
            {
                // 添加新数据
                _historicalReturns.Add(newReturn);

                // 维护数据窗口大小
                if (_historicalReturns.Count > HISTORICAL_WINDOW)
                {
                    _historicalReturns.RemoveAt(0);
                }

                // 标记需要更新模型
                _lastUpdateTime = DateTime.MinValue;
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"更新历史数据失败: {ex.Message}", ex);
            }
        }

        #endregion

        #region 私有计算方法

        /// <summary>
        /// 初始化GARCH模型和波动率聚类分析器
        /// </summary>
        private void InitializeModels()
        {
            if (_historicalReturns.Count < HISTORICAL_WINDOW)
            {
                return;
            }

            try
            {
                // 训练GARCH模型
                _garchModel.EstimateParameters(_historicalReturns.ToArray());

                // 计算历史波动率序列
                var volatilitySequence = CalculateVolatilitySequence();

                // 训练波动率聚类分析器
                _volatilityAnalyzer.PerformKMeansClusterAnalysis(volatilitySequence.ToArray());

                _lastUpdateTime = DateTime.Now;
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"模型初始化失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 检查是否需要更新模型
        /// </summary>
        private bool ShouldUpdateModels()
        {
            var timeSinceUpdate = DateTime.Now - _lastUpdateTime;
            return timeSinceUpdate.TotalMinutes >= UPDATE_INTERVAL_MINUTES ||
                   _lastUpdateTime == DateTime.MinValue;
        }

        /// <summary>
        /// 更新所有模型
        /// </summary>
        private void UpdateModels()
        {
            if (_historicalReturns.Count >= HISTORICAL_WINDOW)
            {
                InitializeModels();
                UpdateCurrentPredictions();
            }
        }

        /// <summary>
        /// 更新当前预测值
        /// </summary>
        private void UpdateCurrentPredictions()
        {
            try
            {
                // 更新GARCH波动率预测
                var predictions = _garchModel.PredictVolatility(
                    Math.Pow(_historicalReturns.Last(), 2), 
                    Enumerable.Range(1, PREDICTION_DAYS).ToArray());
                
                _currentVolatilityPrediction = Math.Sqrt(predictions[0]);
                _volatilityPredictions.Clear();
                _volatilityPredictions.AddRange(predictions.Select(Math.Sqrt));

                // 更新波动率环境分类
                _currentVolatilityEnvironment = ClassifyVolatilityEnvironment(_currentVolatilityPrediction);

                // 更新趋势强度
                _currentTrendStrength = CalculateCurrentTrendStrength();
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"预测值更新失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 计算波动率环境评分
        /// </summary>
        private double CalculateVolatilityEnvironmentScore()
        {
            // 基础评分根据波动率环境确定
            double baseScore;
            double adaptionFactor = 1.0;
            
            // 如果有历史波动率数据，计算自适应因子
            if (_volatilityPredictions.Count > 0)
            {
                // 计算预测波动率的趋势
                double avgPrediction = _volatilityPredictions.Average();
                double currentPrediction = _currentVolatilityPrediction;
                
                // 如果波动率趋于稳定，提高评分
                if (Math.Abs(currentPrediction - avgPrediction) < avgPrediction * 0.1)
                {
                    adaptionFactor = 1.1; // 稳定性奖励
                }
                // 如果波动率在上升，降低评分
                else if (currentPrediction > avgPrediction * 1.2)
                {
                    adaptionFactor = 0.9; // 风险惩罚
                }
            }
            
            // 根据波动率聚类分析结果调整
            double clusterAdjustment = 0;
            if (_volatilityAnalyzer != null)
            {
                var clusterResult = _volatilityAnalyzer.LastClusterResult;
                if (clusterResult != null && clusterResult.IsConverged)
                {
                    // 如果聚类收敛，根据当前状态调整评分
                    switch (clusterResult.CurrentState)
                    {
                        case VolatilityClusterAnalyzer.VolatilityState.Low:
                            clusterAdjustment = 0.1;  // 低波动状态加分
                            break;
                        case VolatilityClusterAnalyzer.VolatilityState.Medium:
                            clusterAdjustment = 0.0;  // 中等波动状态不调整
                            break;
                        case VolatilityClusterAnalyzer.VolatilityState.High:
                            clusterAdjustment = -0.1; // 高波动状态减分
                            break;
                    }
                }
            }
            
            switch (_currentVolatilityEnvironment)
            {
                case ATRCalculator.VolatilityEnvironment.Low:
                    // 低波动环境 - 基础高分，根据市场稳定性调整
                    baseScore = 0.75 + clusterAdjustment;
                    break;
                case ATRCalculator.VolatilityEnvironment.Medium:
                    // 中等波动环境 - 平衡评分
                    baseScore = 0.55 + clusterAdjustment;
                    break;
                case ATRCalculator.VolatilityEnvironment.High:
                    // 高波动环境 - 谨慎评分
                    baseScore = 0.35 + clusterAdjustment;
                    break;
                case ATRCalculator.VolatilityEnvironment.Extreme:
                    // 极端波动环境 - 最低评分，但根据经验调整
                    baseScore = 0.15 + Math.Max(0, clusterAdjustment * 0.5);
                    break;
                default:
                    baseScore = 0.45 + clusterAdjustment;
                    break;
            }
            
            // 应用自适应因子并确保评分在合理范围
            return Math.Max(0.1, Math.Min(1.0, baseScore * adaptionFactor));
        }

        /// <summary>
        /// 计算趋势强度评分
        /// </summary>
        private double CalculateTrendStrengthScore(bool isLongPosition)
        {
            var trendScore = Math.Abs(_currentTrendStrength);
            
            // 根据仓位方向调整评分
            if ((isLongPosition && _currentTrendStrength > 0) || 
                (!isLongPosition && _currentTrendStrength < 0))
            {
                // 趋势方向与仓位方向一致
                return Math.Min(trendScore * 1.2, 1.0);
            }
            else
            {
                // 趋势方向与仓位方向相反
                return Math.Max(trendScore * 0.8, 0.0);
            }
        }

        /// <summary>
        /// 计算GARCH预测评分
        /// </summary>
        private double CalculateGarchPredictionScore()
        {
            if (_volatilityPredictions.Count == 0)
            {
                return 0.5;
            }

            // 基于波动率预测趋势评分
            var volatilityTrend = 0.0;
            for (int i = 1; i < _volatilityPredictions.Count; i++)
            {
                volatilityTrend += (_volatilityPredictions[i] - _volatilityPredictions[i-1]) / _volatilityPredictions[i-1];
            }
            volatilityTrend /= (_volatilityPredictions.Count - 1);

            // 波动率下降趋势得分更高（有利于交易）
            return Math.Max(0.0, Math.Min(1.0, 0.7 - volatilityTrend));
        }

        /// <summary>
        /// 生成交易时机建议
        /// </summary>
        private TimingAdvice GenerateTradingAdvice(double overallScore, bool isLongPosition)
        {
            if (overallScore >= EXCELLENT_TIMING_THRESHOLD)
            {
                return TimingAdvice.Excellent;
            }
            else if (overallScore >= GOOD_TIMING_THRESHOLD)
            {
                return TimingAdvice.Good;
            }
            else if (overallScore >= POOR_TIMING_THRESHOLD)
            {
                return TimingAdvice.Fair;
            }
            else
            {
                return _currentVolatilityEnvironment == ATRCalculator.VolatilityEnvironment.Extreme ? 
                       TimingAdvice.Avoid : TimingAdvice.Poor;
            }
        }

        /// <summary>
        /// 计算历史波动率序列
        /// </summary>
        private List<double> CalculateVolatilitySequence()
        {
            var volatilities = new List<double>();
            const int windowSize = 20; // 20日滚动波动率

            for (int i = windowSize; i < _historicalReturns.Count; i++)
            {
                var window = _historicalReturns.GetRange(i - windowSize, windowSize);
                var mean = window.Average();
                var variance = window.Select(x => Math.Pow(x - mean, 2)).Average();
                var volatility = Math.Sqrt(variance * 252); // 年化波动率
                volatilities.Add(volatility);
            }

            return volatilities;
        }

        /// <summary>
        /// 分类波动率环境
        /// </summary>
        private ATRCalculator.VolatilityEnvironment ClassifyVolatilityEnvironment(double volatility)
        {
            if (volatility <= LOW_VOLATILITY_THRESHOLD)
                return ATRCalculator.VolatilityEnvironment.Low;
            else if (volatility <= MEDIUM_VOLATILITY_THRESHOLD)
                return ATRCalculator.VolatilityEnvironment.Medium;
            else if (volatility <= HIGH_VOLATILITY_THRESHOLD)
                return ATRCalculator.VolatilityEnvironment.High;
            else
                return ATRCalculator.VolatilityEnvironment.Extreme;
        }

        /// <summary>
        /// 计算当前趋势强度
        /// </summary>
        private double CalculateCurrentTrendStrength()
        {
            if (_historicalReturns.Count < 20)
                return 0.0;

            var recentReturns = _historicalReturns.TakeLast(20).ToList();
            
            // 使用线性回归计算趋势强度
            var n = recentReturns.Count;
            var xSum = n * (n - 1) / 2.0;
            var ySum = recentReturns.Sum();
            var xySum = recentReturns.Select((y, i) => i * y).Sum();
            var xSquareSum = n * (n - 1) * (2 * n - 1) / 6.0;

            var denominator = n * xSquareSum - xSum * xSum;
            if (Math.Abs(denominator) < 1e-10)
                return 0.0;

            var slope = (n * xySum - xSum * ySum) / denominator;
            
            // 标准化趋势强度到[-1, 1]区间
            return Math.Max(-1.0, Math.Min(1.0, slope * 100));
        }

        /// <summary>
        /// 估算市场流动性
        /// </summary>
        /// <returns>市场流动性估值</returns>
        private double EstimateMarketLiquidity()
        {
            try
            {
                // 基于历史数据和波动率估算市场流动性
                if (_historicalReturns.Count < 10)
                {
                    return 200.0; // 默认中等流动性
                }

                // 使用波动率的倒数作为流动性指标：波动率越低，流动性越高
                double avgVolatility = _historicalReturns.Select(r => Math.Abs(r)).Average();
                if (avgVolatility == 0) avgVolatility = 0.001; // 避免除零

                double liquidityEstimate = 1.0 / avgVolatility;

                // 限制在合理范围内
                liquidityEstimate = Math.Max(50, Math.Min(1000, liquidityEstimate));

                return liquidityEstimate;
            }
            catch
            {
                return 200.0; // 默认中等流动性
            }
        }

        /// <summary>
        /// 转换波动率环境类型
        /// </summary>
        /// <param name="environment">ATR波动率环境</param>
        /// <returns>TradingTimingScorer波动率环境</returns>
        private TradingTimingScorer.VolatilityEnvironmentLevel ConvertVolatilityEnvironment(
            ATRCalculator.VolatilityEnvironment environment)
        {
            switch (environment)
            {
                case ATRCalculator.VolatilityEnvironment.Low:
                    return TradingTimingScorer.VolatilityEnvironmentLevel.Low;
                case ATRCalculator.VolatilityEnvironment.Medium:
                    return TradingTimingScorer.VolatilityEnvironmentLevel.Medium;
                case ATRCalculator.VolatilityEnvironment.High:
                    return TradingTimingScorer.VolatilityEnvironmentLevel.High;
                case ATRCalculator.VolatilityEnvironment.Extreme:
                    return TradingTimingScorer.VolatilityEnvironmentLevel.Extreme;
                default:
                    return TradingTimingScorer.VolatilityEnvironmentLevel.Medium;
            }
        }

        #endregion

        #region 公共属性

        /// <summary>
        /// 当前波动率环境
        /// </summary>
        public ATRCalculator.VolatilityEnvironment CurrentVolatilityEnvironment => _currentVolatilityEnvironment;

        /// <summary>
        /// 当前波动率预测值
        /// </summary>
        public double CurrentVolatilityPrediction => _currentVolatilityPrediction;

        /// <summary>
        /// 当前趋势强度
        /// </summary>
        public double CurrentTrendStrength => _currentTrendStrength;

        /// <summary>
        /// 最后一次评分结果
        /// </summary>
        public TradingTimingScore LastTimingScore => _lastTimingScore;

        /// <summary>
        /// 历史数据数量
        /// </summary>
        public int HistoricalDataCount => _historicalReturns.Count;

        #endregion
    }

    #region 辅助数据结构

    /// <summary>
    /// 交易时机建议
    /// </summary>
    public enum TimingAdvice
    {
        Excellent,  // 优秀时机
        Good,       // 良好时机
        Fair,       // 一般时机
        Poor,       // 较差时机
        Caution,    // 谨慎交易
        Avoid       // 避免交易
    }

    /// <summary>
    /// 交易时机评分结果
    /// </summary>
    public class TradingTimingScore
    {
        public double OverallScore { get; set; }                     // 综合评分
        public double VolatilityScore { get; set; }                 // 波动率评分
        public double TrendScore { get; set; }                      // 趋势评分
        public double PredictionScore { get; set; }                 // 预测评分
        public ATRCalculator.VolatilityEnvironment VolatilityEnvironment { get; set; } // 波动率环境
        public double PredictedVolatility { get; set; }             // 预测波动率
        public double TrendStrength { get; set; }                   // 趋势强度
        public TimingAdvice TimingAdvice { get; set; }              // 时机建议
        public DateTime CalculationTime { get; set; }               // 计算时间
        public bool IsReliable { get; set; }                        // 结果可靠性
        public string ErrorMessage { get; set; }                    // 错误信息

        /// <summary>
        /// 获取评分等级描述
        /// </summary>
        public string GetScoreGrade()
        {
            if (OverallScore >= TradingTimingOptimizer.EXCELLENT_TIMING_THRESHOLD)
                return "优秀";
            else if (OverallScore >= TradingTimingOptimizer.GOOD_TIMING_THRESHOLD)
                return "良好";
            else if (OverallScore >= TradingTimingOptimizer.POOR_TIMING_THRESHOLD)
                return "一般";
            else
                return "较差";
        }

        /// <summary>
        /// 生成详细报告
        /// </summary>
        public string GenerateDetailedReport()
        {
            return $"=== 交易时机评分报告 ===\n" +
                   $"综合评分: {OverallScore:P2} ({GetScoreGrade()})\n" +
                   $"波动率环境: {VolatilityEnvironment} (评分: {VolatilityScore:P2})\n" +
                   $"趋势强度: {TrendStrength:F4} (评分: {TrendScore:P2})\n" +
                   $"预测评分: {PredictionScore:P2}\n" +
                   $"预测波动率: {PredictedVolatility:P2}\n" +
                   $"时机建议: {TimingAdvice}\n" +
                   $"计算时间: {CalculationTime:yyyy-MM-dd HH:mm:ss}\n" +
                   $"结果可靠: {(IsReliable ? "是" : "否")}\n" +
                   $"{(string.IsNullOrEmpty(ErrorMessage) ? "" : $"错误信息: {ErrorMessage}")}" +
                   "========================";
        }
    }

    #endregion
}
